package net.beeapm.demo.controller;

import com.alibaba.fastjson.JSON;
import net.beeapm.demo.model.RequestVo;
import net.beeapm.demo.model.ResultVo;
import net.beeapm.demo.service.IHelloService;
import net.beeapm.demo.skywalking.AlarmMessage;
import net.beeapm.demo.skywalking.TraceCrossCallable;
import org.apache.skywalking.apm.toolkit.trace.RunnableWrapper;
import org.apache.skywalking.apm.toolkit.trace.SupplierWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author yuan
 * @date 2020/01/12
 */
@RequestMapping("/hello")
@RestController
public class HelloController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());


    ExecutorService executorService = Executors.newFixedThreadPool(1);


    @Autowired
    private IHelloService service;

    @RequestMapping("/world")
    public ResultVo world(String req) throws InterruptedException {

        //演示 异步传递 trace 标志
        CountDownLatch latch = new CountDownLatch(1);
        executorService.submit(new TraceCrossCallable(latch));

        latch.await();

        logger.debug(JSON.toJSONString(req));
        return service.sayGoodbye(new RequestVo());
    }

    @RequestMapping("/world2")
    public ResultVo world2(String req) throws InterruptedException {

        //演示 异步传递 trace 标志
        CountDownLatch latch = new CountDownLatch(1);
        executorService.submit(RunnableWrapper.of(new Runnable() {
            @Override
            public void run() {
                //your code

                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                latch.countDown();
            }
        }));

        latch.await();

        logger.debug(JSON.toJSONString(req));
        return service.sayGoodbye(new RequestVo());
    }

    @RequestMapping("/world3")
    public ResultVo world3(String req) throws InterruptedException {

        //演示 异步传递 trace 标志
        CountDownLatch latch = new CountDownLatch(1);


        CompletableFuture.supplyAsync(SupplierWrapper.of(() -> {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            latch.countDown();
            return "SupplierWrapper";
        }), executorService);

        latch.await();

        logger.debug(JSON.toJSONString(req));
        return service.sayGoodbye(new RequestVo());
    }

    @RequestMapping("/world4")
    public ResultVo world4(String req) throws InterruptedException {

        //演示 告警
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


        logger.debug(JSON.toJSONString(req));
        return service.sayGoodbye(new RequestVo());
    }


    @PostMapping("/hook")
    public ResultVo hook(@RequestBody List<AlarmMessage> alarmMessageList) throws InterruptedException {

        //演示 告警 回调
        Iterator<AlarmMessage> iterator = alarmMessageList.iterator();
        while (iterator.hasNext()) {
            AlarmMessage next = iterator.next();

            System.out.println("next = " + next);
        }

        return service.sayGoodbye(new RequestVo());
    }


    @RequestMapping("/sayGoodbye")
    public ResultVo sayGoodbye(@RequestBody RequestVo req) {
        logger.debug(JSON.toJSONString(req));
        return service.sayGoodbye(req);
    }

    @RequestMapping("/sayHello")
    public ResultVo sayHello(@RequestBody RequestVo req) {
        logger.debug(JSON.toJSONString(req));
        logger.trace("Log4j2==================>trace");
        logger.debug("Log4j2==================>debug");
        logger.info("Log4j2==================>info");
        logger.warn("Log4j2==================>warn");
        logger.error("Log4j2==================>error");

        return service.sayHello(req);
    }

    @RequestMapping("/welcomeChina")
    public ResultVo welcomeChina(@RequestBody RequestVo req) {
        logger.debug(JSON.toJSONString(req));
        return service.welcomeChina(req);
    }

    @RequestMapping("/welcomeXiaMen")
    public ResultVo welcomeXiaMen(@RequestBody RequestVo req) {
        logger.debug(JSON.toJSONString(req));
        return service.welcomeXiaMen(req);
    }


}
